package graphicsExtended.animation.panelDrawer;

import graphicsExtended.animation.animationSequence.AnimationSequence;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Point;
import java.awt.image.BufferedImage;
import java.util.concurrent.LinkedBlockingQueue;
import time.Timer;
import tuples.Pair;

/**
 *
 * @author Shimu
 * @date 9-Nov-2012
 */
public class Layer {

    private final BufferedImage IMAGE;

    private final Graphics2D GRAPHICS;

    private final LinkedBlockingQueue<AnimationSequence> QUEUE =
            new LinkedBlockingQueue<AnimationSequence>();

    protected Layer(int width, int height) {
        this.IMAGE = new BufferedImage(width, height,
                BufferedImage.TYPE_INT_ARGB);
        this.GRAPHICS = IMAGE.createGraphics();
    }

    protected Graphics2D getGraphics() {
        return GRAPHICS;
    }
    
    public void setImage(BufferedImage img) {
        this.GRAPHICS.drawImage(img, 0, 0, null);
    }
    
    public BufferedImage getImage() {
        return IMAGE;
    }

    public long drawAll() {
        Timer timer = new Timer(false);
        timer.start();

        LinkedBlockingQueue<AnimationSequence> updated =
                new LinkedBlockingQueue<AnimationSequence>();

        while (!QUEUE.isEmpty()) {
            AnimationSequence sequence = QUEUE.poll();
            switch (sequence.getStatus()) {
                case AnimationSequence.STATUS_NO_MORE_FRAMES:
                    // do nothing
                    break;
                case AnimationSequence.STATUS_SKIP_FRAME:
                    // Send it to the update queue without doing anything
                    updated.offer(sequence);
                    break;
                case AnimationSequence.STATUS_FRAME_READY:
                    Pair<Image, Point> tuple = sequence.getNextFrame();
                    Image img = tuple.getFirst();
                    Point pt = tuple.getSecond();

                    GRAPHICS.drawImage(img, pt.x, pt.y, null);
                    updated.offer(sequence);
                    break;
            }
        }
        updated.drainTo(QUEUE);

        return timer.getElapsedTime();
    }

    public void push(AnimationSequence obj) {
        this.QUEUE.offer(obj);
    }
}
